import datetime, time, jwt,logging

from flask import jsonify
from app.users.model import Users
from app import config
from app import _common


class Auth(object):

	#: 返回jwt编码后 payload
	@staticmethod
	def encode_auth_token(user_id, login_time):
		try:
			payload = {
				'iss': 'ken',	#发行方
				'exp': datetime.datetime.utcnow() + datetime.timedelta(days=0, seconds=60),	# 过期时间
				'iat': datetime.datetime.utcnow(),	# 签发时间
				'data': {
					'id': user_id,
					'login_time': login_time
				}
			}
			
			return jwt.encode(
				payload,
				config.SECRET_KEY,
				algorithm='HS256'
			)
		except Exception as e:
			return e

	#: 返回jwt解密后 payload
	@staticmethod
	def decode_auth_token(auth_token):
		try:
			# payload = jwt.decode(auth_token, app.config.get('SECRET_KEY'), leeway=datetime.timedelta(seconds=10))
			# 取消过期时间验证
			payload = jwt.decode(auth_token, config.SECRET_KEY, algorithms=['HS256'], options={'verify_exp': False})
			if ('data' in payload and 'id' in payload['data']):
				return payload
			else:
				raise jwt.InvalidTokenError
		except jwt.ExpiredSignatureError:
			return 'Token过期'
		except jwt.InvalidTokenError:
			return '无效Token'

	#: 验证用户名、密码，成功则返回token
	@staticmethod
	def authenticate(username, password):
		
		userInfo = Users.query.filter_by(username=username).first()
		if (userInfo is None):
			return jsonify(_common.falseReturn('', '找不到用户'))
		else:
			if (Users.check_password(Users, userInfo.password, password)):
				login_time = int(time.time())	# 登录一次重新获取一次登录时间
				userInfo.login_time = login_time
				userInfo.update()
				#: 制作 token
				token = Auth.encode_auth_token(userInfo.id, login_time)
				logging.info('token: '+ str(token))
				return jsonify(_common.trueReturn(token.decode(), '登录成功'))
			else:
				return jsonify(_common.falseReturn('', '密码不正确'))

	#: 验证 token 则返回请求的资源
	@staticmethod
	def identify(auth_header):
		result = {}
		if (auth_header):
			auth_tokenArr = auth_header.split(':')	#: 头信息由(jwt + ':' + token)组成
			logging.info('auth_tokenArr: ' + str(auth_tokenArr))
			if (auth_tokenArr[0] != 'jwt' or len(auth_tokenArr) != 2):
				result = _common.falseReturn('', '请传递正确的验证头信息')
			else:
				auth_token = auth_tokenArr[1]
				payload = Auth.decode_auth_token(auth_token)	#: 解码token 返回 payload
				logging.info('payload: ' + str(payload))
				if not isinstance(payload, str):
					user = Users.get_by_id(payload['data']['id'])
					
					if (user is None):
						result = _common.falseReturn('', '找不到该用户信息')
					else:
						if (user.login_time == payload['data']['login_time']):
							result = _common.trueReturn(user.id, '请求成功')
						else:
							result = _common.falseReturn('', 'Token已过期，请重新登录获取')
				else:
					result = _common.falseReturn('', payload)
		else:
			result = _common.falseReturn('', '没有提供认证token')
		return result